﻿#include "DLLInjectorCommand.h"
#ifdef _DEBUG
#include <fast_io/fast_io_device.h>

#include "../../../Memory/GameData.h"

fast_io::vector<fast_io::native_dll_file> dlls{};

bool DLLInjectorCommand_onExecute(const fast_io::vector<std::u8string>& args) {
	if (args.size() < 2)
		return false;

	if (args.size() == 2 && args[1] == u8"close") {
		dlls.clear();

		switch (SettingManager::languageget) {
		case 0:
		default:
			C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
											 u8"[Helium] ",
											 Utils::TextColor::YELLOW,
											 u8"All dlls unloaded!");
			break;
		case 1:
			C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
											 u8"[Helium] ",
											 Utils::TextColor::YELLOW,
											 u8"已卸载所有dll");
			break;
		case 2:
			C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
											 u8"[Helium] ",
											 Utils::TextColor::YELLOW,
											 u8"已卸載所有dll");
			break;
		case 3:
			C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
											 u8"[Helium] ",
											 Utils::TextColor::YELLOW,
											 u8"すべてのDLLをアンインストールしました");
			break;
			std::unreachable();
		}
	}

	std::u8string concatstr{};
	for (size_t i = 1; i < args.size(); i++) {
		concatstr.append(args[i]);
		if (i != args.size() - 1) [[likely]]
			concatstr.push_back(u8' ');
	}

	//inject
	try {
		dlls.emplace_back(concatstr, fast_io::dll_mode::posix_rtld_lazy);
	} catch (const fast_io::error& e) {
		switch (SettingManager::languageget) {
		case 0:
		default:
			C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
											 u8"[Helium] ",
											 Utils::TextColor::RED,
											 u8"Inject failed: ",
											 e);
			break;
		case 1:
			C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
											 u8"[Helium] ",
											 Utils::TextColor::RED,
											 u8"注入失败: ",
											 e);
			break;
		case 2:
			C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
											 u8"[Helium] ",
											 Utils::TextColor::RED,
											 u8"註入失敗: ",
											 e);
			break;
		case 3:
			C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
											 u8"[Helium] ",
											 Utils::TextColor::RED,
											 u8"インジェクションに失敗しました: ",
											 e);
			break;
			std::unreachable();
		}
		return true;
	}
	switch (SettingManager::languageget) {
	case 0:
	default:
		C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
										 u8"[Helium] ",
										 Utils::TextColor::GREEN,
										 u8"Successfully inject!");
		break;
	case 1:
		C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
										 u8"[Helium] ",
										 Utils::TextColor::GREEN,
										 u8"注入成功!");
		break;
	case 2:
		C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
										 u8"[Helium] ",
										 Utils::TextColor::GREEN,
										 u8"註入成功");
		break;
	case 3:
		C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
										 u8"[Helium] ",
										 Utils::TextColor::GREEN,
										 u8"注射に成功しました");
		break;
		std::unreachable();
	}
	return true;
}

ICommand DLLInjectorCommand{
	u8"injectdll",
	u8".injectdll or .injdll <dll file path>",
	{u8"Inject dll", u8"注入dll", u8"註入dll", u8"DLL を挿入する"},
	{u8"injdll"},
	fast_io::vector<aliasList_struct>{},  // If empty must use fast_io::vector<aliasList_struct>{}
	nullptr,
	&DLLInjectorCommand_onExecute};
#endif  // DEBUG
